home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / frasr182.zip / HELP.C < prev    next >
C/C++ Source or Header  |  1993-08-02  |  38KB  |  1,674 lines

  1. /*
  2.  * help.c
  3.  *
  4.  * This module is linked as an overlay, use ENTER_OVLY and EXIT_OVLY.
  5.  *
  6.  *
  7.  * Revision history:
  8.  *
  9.  *   2-26-90  EAN     Initial version.
  10.  *
  11.  *
  12.  */
  13.  
  14.  
  15. #ifndef TEST /* kills all those assert macros in production version */
  16. #define NDEBUG
  17. #endif
  18.  
  19. #define INCLUDE_COMMON    /* include common code in helpcom.h */
  20.  
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #ifndef XFRACT
  25. #include <io.h>
  26. #include <dos.h>
  27. #endif
  28. #include <fcntl.h>
  29. #include <string.h>
  30. #include <time.h>
  31. #include <assert.h>
  32. #include <sys/types.h>
  33. #include <sys/stat.h>
  34. #ifdef XFRACT
  35. #include <unistd.h>
  36. #endif
  37. #include "fractint.h"
  38. #include "helpcom.h"
  39. #include "helpdefs.h"
  40. #include "prototyp.h"
  41.  
  42.  
  43. #define MAX_HIST       16         /* number of pages we'll remember */
  44.  
  45. #define ALT_F1         1104
  46. #define BACK_TAB     1015
  47. #define BACKSPACE        8
  48.  
  49. #define ACTION_CALL        0         /* values returned by help_topic() */
  50. #define ACTION_PREV        1
  51. #define ACTION_PREV2        2         /* special - go back two topics */
  52. #define ACTION_INDEX        3
  53. #define ACTION_QUIT        4
  54.  
  55. #define F_HIST            (1<<0)   /* flags for help_topic() */
  56. #define F_INDEX         (1<<1)
  57.  
  58. #define MAX_PAGE_SIZE        (80*25)  /* no page of text may be larger */
  59.  
  60. #define TEXT_START_ROW        2         /* start print the help text here */
  61.  
  62.  
  63. typedef struct
  64.    {
  65.    BYTE r, c;
  66.    int         width;
  67.    unsigned     offset;
  68.    int         topic_num;
  69.    unsigned     topic_off;
  70.    } LINK;
  71.  
  72.  
  73. typedef struct
  74.    {
  75.    int        topic_num;
  76.    unsigned topic_off;
  77.    } LABEL;
  78.  
  79.  
  80. typedef struct
  81.    {
  82.    unsigned     offset;
  83.    unsigned     len;
  84.    int         margin;
  85.    } PAGE;
  86.  
  87.  
  88. typedef struct
  89.    {
  90.    int        topic_num;
  91.    unsigned topic_off;
  92.    int        link;
  93.    } HIST;
  94.  
  95.  
  96. struct help_sig_info
  97.    {
  98.    unsigned long sig;
  99.    int         version;
  100.    unsigned long base;       /* only if added to fractint.exe */
  101.    } ;
  102.  
  103.  
  104. void print_document(char *outfname, int (*msg_func)(int,int), int save_extraseg );
  105. static int print_doc_msg_func(int pnum, int num_pages);
  106.  
  107.  
  108.  
  109. void help_overlay(void) { }
  110.  
  111.  
  112.  
  113. /* stuff from fractint */
  114.  
  115. extern int  lookatmouse;
  116. extern long timer_start;
  117. extern int  helpmode;
  118. extern int  text_type;     /* 0=real color text, 1=640x200x2, 2=??mono?? */
  119. extern int  textcbase;
  120. extern int  textrbase;
  121. extern SEGTYPE  extraseg;
  122. extern int  release;
  123.  
  124. int  putstringcenter (int row, int col, int width, int attr, char far *msg);
  125. void helptitle         (void);
  126. void stackscreen     (void);
  127. void unstackscreen   (void);
  128. void findpath         (char *filename, char *path);
  129.  
  130.  
  131. static int          help_file = -1; /* help file handle */
  132. static long          base_off;       /* offset to help info in help file */
  133. static int          max_links;      /* max # of links in any page */
  134. static int          max_pages;      /* max # of pages in any topic */
  135. static int          num_label;      /* number of labels */
  136. static int          num_topic;      /* number of topics */
  137. static int          curr_hist = 0;  /* current pos in history */
  138.  
  139. /* these items alloc'ed in init_help... */
  140.  
  141. static long     far *topic_offset;       /* 4*num_topic */
  142. static LABEL     far *label;           /* 4*num_label */
  143. static HIST     far *hist;           /* 6*MAX_HIST (96 bytes) */
  144.  
  145. /* these items alloc'ed only while help is active... */
  146.  
  147. static char      far *buffer;         /* MAX_PAGE_SIZE (2048 bytes) */
  148. static LINK      far *link_table;     /* 10*max_links */
  149. static PAGE      far *page_table;     /* 4*max_pages  */
  150.  
  151.  
  152. static void help_seek(long pos)
  153.    {
  154.    lseek(help_file, base_off+pos, SEEK_SET);
  155.    }
  156.  
  157.  
  158. static void displayc(int row, int col, int color, int ch)
  159.    {
  160. #ifndef XFRACT
  161.    static char *s = "?";
  162. #else
  163.    static char s[] = "?";
  164. #endif
  165.  
  166.    if (text_type == 1)     /* if 640x200x2 mode */
  167.       {
  168.       /*
  169.        * This is REALLY ugly, but it works.  Non-current links (ones that
  170.        * would be bold if 640x200 supported it) are in upper-case and the
  171.        * current item is inversed.
  172.        *
  173.        */
  174.  
  175.       if (color & INVERSE)
  176.      color = (signed int)INVERSE;
  177.       else if (color & BRIGHT)
  178.      {
  179.      color = 0;   /* normal */
  180.      if (ch>='a' && ch<='z')
  181.         ch += 'A' - 'a';
  182.      }
  183.       else
  184.      color = 0;   /* normal */
  185.       }
  186.  
  187.    s[0] = ch;
  188.    putstring(row, col, color, s);
  189.    }
  190.  
  191.  
  192. static void display_text(int row, int col, int color, char far *text, unsigned len)
  193.    {
  194.    while (len-- > 0)
  195.       {
  196.       if (*text == CMD_LITERAL)
  197.      {
  198.      ++text;
  199.      --len;
  200.      }
  201.       displayc(row, col++, color, *text++);
  202.       }
  203.    }
  204.  
  205.  
  206. static void display_parse_text(char far *text, unsigned len, int start_margin, int *num_link, LINK far *link)
  207.    {
  208.    char far  *curr;
  209.    int          row, col;
  210.    int          tok;
  211.    int          size,
  212.           width;
  213.  
  214.    textcbase = SCREEN_INDENT;
  215.    textrbase = TEXT_START_ROW;
  216.  
  217.    curr = text;
  218.    row = 0;
  219.    col = 0;
  220.  
  221.    size = width = 0;
  222.  
  223.    if (start_margin >= 0)
  224.       tok = TOK_PARA;
  225.    else
  226.       tok = -1;
  227.  
  228.    while ( 1 )
  229.       {
  230.       switch ( tok )
  231.      {
  232.      case TOK_PARA:
  233.         {
  234.         int indent,
  235.         margin;
  236.  
  237.         if (size > 0)
  238.            {
  239.            ++curr;
  240.            indent = *curr++;
  241.            margin = *curr++;
  242.            len  -= 3;
  243.            }
  244.         else
  245.            {
  246.            indent = start_margin;
  247.            margin = start_margin;
  248.            }
  249.  
  250.         col = indent;
  251.  
  252.         while (1)
  253.            {
  254.            tok = find_token_length(ONLINE, curr, len, &size, &width);
  255.  
  256.            if (tok == TOK_DONE || tok == TOK_NL || tok == TOK_FF )
  257.           break;
  258.  
  259.            if (tok == TOK_PARA)
  260.           {
  261.           col = 0;   /* fake a new-line */
  262.           row++;
  263.           break;
  264.           }
  265.  
  266.            if (tok == TOK_XONLINE || tok == TOK_XDOC)
  267.           {
  268.           curr += size;
  269.           len  -= size;
  270.           continue;
  271.           }
  272.  
  273.            /* now tok is TOK_SPACE or TOK_LINK or TOK_WORD */
  274.  
  275.            if (col+width > SCREEN_WIDTH)
  276.           {         /* go to next line... */
  277.           col = margin;
  278.           ++row;
  279.  
  280.           if ( tok == TOK_SPACE )
  281.              width = 0;   /* skip spaces at start of a line */
  282.           }
  283.  
  284.            if (tok == TOK_LINK)
  285.           {
  286.           display_text(row, col, C_HELP_LINK, curr+1+3*sizeof(int), width);
  287.           if (num_link != NULL)
  288.              {
  289.              link[*num_link].r           = row;
  290.              link[*num_link].c           = col;
  291.                      link[*num_link].topic_num = getint(curr+1);
  292.                      link[*num_link].topic_off = getint(curr+1+sizeof(int));
  293.                      link[*num_link].offset    = (unsigned) ((curr+1+3*sizeof(int)) - text);
  294.              link[*num_link].width     = width;
  295.              ++(*num_link);
  296.              }
  297.           }
  298.            else if (tok == TOK_WORD )
  299.           display_text(row, col, C_HELP_BODY, curr, width);
  300.  
  301.            col += width;
  302.            curr += size;
  303.            len -= size;
  304.            }
  305.  
  306.         width = size = 0;
  307.         break;
  308.         }
  309.  
  310.      case TOK_CENTER:
  311.         col = find_line_width(ONLINE, curr, len);
  312.         col = (SCREEN_WIDTH-col)/2;
  313.         if (col < 0)
  314.            col = 0;
  315.         break;
  316.  
  317.      case TOK_NL:
  318.         col = 0;
  319.         ++row;
  320.         break;
  321.  
  322.      case TOK_LINK:
  323.             display_text(row, col, C_HELP_LINK, curr+1+3*sizeof(int), width);
  324.         if (num_link != NULL)
  325.            {
  326.            link[*num_link].r     = row;
  327.            link[*num_link].c     = col;
  328.                link[*num_link].topic_num = getint(curr+1);
  329.                link[*num_link].topic_off = getint(curr+1+sizeof(int));
  330.                link[*num_link].offset    = (unsigned) ((curr+1+3*sizeof(int)) - text);
  331.            link[*num_link].width     = width;
  332.            ++(*num_link);
  333.            }
  334.         break;
  335.  
  336.      case TOK_XONLINE:  /* skip */
  337.      case TOK_FF:        /* ignore */
  338.      case TOK_XDOC:     /* ignore */
  339.      case TOK_DONE:
  340.      case TOK_SPACE:
  341.         break;
  342.  
  343.      case TOK_WORD:
  344.         display_text(row, col, C_HELP_BODY, curr, width);
  345.         break;
  346.      } /* switch */
  347.  
  348.       curr += size;
  349.       len  -= size;
  350.       col  += width;
  351.  
  352.       if (len == 0)
  353.      break;
  354.  
  355.       tok = find_token_length(ONLINE, curr, len, &size, &width);
  356.       } /* while */
  357.  
  358.    textcbase = 0;
  359.    textrbase = 0;
  360.    }
  361.  
  362.  
  363. static void color_link(LINK far *link, int color)
  364.    {
  365.    textcbase = SCREEN_INDENT;
  366.    textrbase = TEXT_START_ROW;
  367.  
  368.    if (text_type == 1)     /* if 640x200x2 mode */
  369.       display_text(link->r, link->c, color, buff